pub struct Solution;


impl Solution {
    // pub fn Solution::check_inclusion(s1: String, s2: String) -> bool {
    //     if s1.len() <= s2.len() {
    //         let req_len = s1.len();
    //         let mut now_len = 0;
    //         // 记录数量 因为允许s1重复
    //         let mut records = [0; 26];
    //         let mut exit = [false; 26];
    //         for i in s1.bytes() {
    //             let tmp = (i - b'a') as usize;
    //             records[tmp] += 1;
    //             exit[tmp] = true;
    //         }
    //         // 三种情况
    //         // 1. 不在s1内的，那么整个序列都被截断了，归还凭证，重置长度
    //         // 2. 在s1内的，还有凭证的，那么减去凭证，并查看长度
    //         // 3. 在s1内，但是没有凭证了，需要归还最左的凭证
    //         let bytes = s2.into_bytes();
    //         for (i, val) in bytes.iter().enumerate() {
    //             let tmp = (val - b'a') as usize;
    //             if exit[tmp] {
    //                 // 凭证是否还有
    //                 if records[tmp] > 0 {
    //                     // 第2中情况
    //                     // 减去凭证
    //                     records[tmp] -= 1;
    //                     // 长度加1
    //                     now_len += 1;
    //                     if now_len == req_len {
    //                         return true;
    //                     }
    //                 } else {
    //                     // 第3中情况
    //                     // 需要归还凭证直到符合要求
    //                     let start = i - now_len;
    //                     for j in &bytes[start..i] {
    //                         // 归还凭证
    //                         let k = (*j - b'a') as usize;
    //                         // 如果相同
    //                         if k == tmp {
    //                             // 不用归还，一切不变
    //                             break;
    //                         } else {
    //                             // 归还
    //                             now_len -= 1;
    //                             records[k] += 1;
    //                         }
    //                     }
    //                 }
    //             } else {
    //                 // 第一种情况
    //                 // 归还凭证
    //                 let start = i - now_len;
    //                 for j in &bytes[start..i] {
    //                     records[(*j - b'a') as usize] += 1;
    //                 }
    //                 // 重置长度
    //                 now_len = 0;
    //             }
    //         }
    //     }
    //
    //     false
    // }

    pub fn check_inclusion(s1: String, s2: String) -> bool {
        let (l1, l2) = (s1.len(), s2.len());
        if l1 > l2 {
            return false;
        }
        let (mut c1, mut c2) = ([0; 26], [0; 26]);
        let s2: Vec<usize> = s2.bytes().map(|b| (b - b'a') as usize).collect();
        s1.bytes()
            .map(|b| (b - b'a') as usize)
            .for_each(|i| c1[i] += 1);
        s2.iter().take(l1).for_each(|i| c2[*i] += 1);
        c1 == c2
            || (0..l2 - l1).any(|i| {
            c2[s2[i]] -= 1;
            c2[s2[i + l1]] += 1;
            c1 == c2
        })
    }
}


#[cfg(test)]
mod test {
    use crate::Solution;

    #[test]
    fn test_01() {
        let res = Solution::check_inclusion("ab".to_string(), "eidbaooo".to_string());
        assert_eq!(res, true);
    }

    #[test]
    fn test_02() {
        let res = Solution::check_inclusion("ab".to_string(), "eidboaoo".to_string());
        assert_eq!(res, false);
    }

    #[test]
    fn test_03() {
        let res = Solution::check_inclusion("adc".to_string(), "dcda".to_string());
        assert_eq!(res, true);
    }

    #[test]
    fn test_04() {
        let res = Solution::check_inclusion("aa".to_string(), "eidccbcccaaooo".to_string());
        assert_eq!(res, true);
    }

    #[test]
    fn test_05() {
        let res = Solution::check_inclusion("abc".to_string(), "ccccbbbbaaaa".to_string());
        assert_eq!(res, false);
    }
}

fn main() {
    let res = Solution::check_inclusion("abc".to_string(), "ccccbbbbaaaa".to_string());
    assert_eq!(res, false);
}
